package com.ocom.netty.mj.ropo;


import com.ocom.netty.mj.util.CRC16;
import com.ocom.netty.mj.util.DES;
import com.ocom.netty.mj.util.NumConvertUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 门禁tcp通信
 */

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TcpServiceRopo {
    //包头STX 2字节  ca ac
    String stx="caac";

    //数据长度 2个字节
    String strLength ="0000";

    //版本 1个字节
    String edition="00";

    //类型 1个字节
    String type="00";

    //终端地址 4个字节
    String machId="00000000";

    //请求应答标识 1个字节
    //0x01：请求
    //0x02：应答
    String respTip="00";

    //包号  4个字节
    String packageNum="00000000";

    //SessionID  4个字节
    String sessionId="00000000";


    /**
     * 数据域
     */
    //命令类型  2个字节
    String  commandType="0000";

    //命令类型  2个字节
    String  commandLength="0000";

    //命令参数  不定长 默认1
    String  commandParam="00";

    //加密校验 8个字节
    String sign="0000000000000000";


    //包尾ETX   2个字节
    String ext="acca";


    //命令参数长度为0的时候 tcp长最小33个字节
    public  TcpServiceRopo(byte[] bytes)  {

        String messageData=NumConvertUtil.bytesToHexString(bytes);

        //开头
        this.stx=NumConvertUtil.byteToHex(bytes[0],bytes[1]);

        //结尾
        this.ext=NumConvertUtil.byteToHex(bytes[bytes.length-2],bytes[bytes.length-1]);

        //长度
        this.strLength=NumConvertUtil.byteToHex(bytes[2],bytes[3]);

        this.edition=NumConvertUtil.byteToHex(bytes[4]);

        this.type=NumConvertUtil.byteToHex(bytes[5]);

        this.machId=NumConvertUtil.byteToHex(bytes[6],bytes[7],bytes[8],bytes[9]);

        this.respTip=NumConvertUtil.byteToHex(bytes[10]);

        this.packageNum=NumConvertUtil.byteToHex(bytes[11],bytes[12],bytes[13],bytes[14]);

        this.sessionId=NumConvertUtil.byteToHex(bytes[15],bytes[16],bytes[17],bytes[18]);

        this.commandType=NumConvertUtil.byteToHex(bytes[19],bytes[20]);

        this.commandLength=NumConvertUtil.byteToHex(bytes[21],bytes[22]);

        byte[] paramBytes=new byte[Integer.parseInt(this.commandLength,16)];
        for(int i=23;i<=bytes.length-11;i++){
            paramBytes[i-23]=bytes[i];
        }

        this.commandParam=NumConvertUtil.byteToHex(paramBytes);

        byte[] signBytes=new byte[8];
        for(int i=bytes.length-10;i<bytes.length-2;i++){
            signBytes[i-(bytes.length-10)]=bytes[i];
        }

        this.sign=NumConvertUtil.byteToHex(signBytes);
    }


    public String getHexStr() throws Exception {


        byte[] params=NumConvertUtil.hexStringToByte(this.commandParam);
        //整体长度  strLength 修改 10转16
        String len2=Integer.toHexString(params.length);
        this.commandLength="0000";
        StringBuilder stringBuilder2=new StringBuilder(this.strLength);
        stringBuilder2.replace(this.commandLength.length()-len2.length(),this.commandLength.length(),len2);
        this.commandLength=stringBuilder2.toString();


        //整体长度  strLength 修改 10转16
        String len=Integer.toHexString(params.length+27);
        this.strLength="0000";
        StringBuilder stringBuilder=new StringBuilder(this.strLength);
        stringBuilder.replace(this.strLength.length()-len.length(),this.strLength.length(),len);
        this.strLength=stringBuilder.toString();

        //校验数据:
        String yanqian=this.edition+this.type+this.machId+this.respTip+this.packageNum+this.sessionId+this.commandType+this.commandLength+this.commandParam;

        //crc16
        int crc= CRC16.calcCrc16(NumConvertUtil.hexStringToByte(yanqian));
        String crcHexStr=NumConvertUtil.reverseHex(NumConvertUtil.IntToHexStringNum(crc,4));

        //异或和
        String yhh=NumConvertUtil.hexYihuo(yanqian);
        if(yhh.length()==1){
            yhh="0"+yhh;
        }

        //累加和
        String ljh=NumConvertUtil.hexLeijia(yanqian);
        if(ljh.length()==1){
            ljh="0"+ljh;
        }

        //包号
        String packageNum=this.getPackageNum();

        //验签
        String signData=packageNum+crcHexStr+yhh+ljh;

        //des加密
        DES des = new DES(NumConvertUtil.hexStringToByte("0044C3D1237CA268"));
        byte[] bytes1 = des.encrypt(NumConvertUtil.hexStringToByte(signData));
        this.sign=NumConvertUtil.bytesToHexString(bytes1).substring(0, 16);

        return this.stx+this.strLength+yanqian+this.sign+this.ext;
    }


//    public String getMachIdTen() {
//        return NumConvertUtil.HexStringToInt(this.machId).toString();
//    }
}
